package com.miracle9.game.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.apache.mina.core.session.IoSession;

public class MyUtil {

    private static Logger logger = Logger.getLogger(MyUtil.class);
    public static int bS = 32767;
    public static Random aw = new Random();
    public static String bT = "2015ghdz2016WMCY=！#games";
    private static String bU = "Qzh0Qxebwie8Kvse";

    public static String substringLength(int length) {
        try {
            String src = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz";
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++) {
                int index = (int) (Math.random() * src.length());
                if (index < src.length()) {
                    sb.append(src.substring(index, index + 1));
                }
            }
            return sb.toString();
        } catch (Exception localException) {
        }
        return "";
    }

    public static byte[] writeIntStream(int i) {
        try {
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(buf);
            out.writeInt(i);
            byte[] b = buf.toByteArray();
            out.close();
            buf.close();
            return b;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int readIntStream(byte[] bytes) {
        try {
            ByteArrayInputStream bytein = new ByteArrayInputStream(bytes);
            DataInputStream in = new DataInputStream(bytein);
            int i = in.readInt();
            bytein.close();
            in.close();
            return i;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    public static String dateFormatYMD_HMS_Sting(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public static String c() {
        return dateFormatYMD_HMS_Sting(new Date());
    }

    public static String dateFormatYMD_Sting(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }

    public static Date dateFormatYMD_HMS(String dateStr) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Date();
    }

    public static Date dateFormatYMD(String dateStr) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Date();
    }

    public static Date dateStrParse(String dateStr, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Date();
    }

    public static byte[] Base64Encode_session(byte[] bytes, IoSession session) throws Exception {
        if (GameParameterAssist.bd.containsKey(session)) {
            String key = (String) GameParameterAssist.bd.get(session);
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(bU.getBytes("utf-8"));
            cipher.init(1, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(bytes);

            return new Base64().encode(encrypted);
        }
        return bytes;
    }

    public static byte[] Base64Decode_session(byte[] bytes, IoSession session) throws Exception {
        try {
            if (GameParameterAssist.bd.containsKey(session)) {
                String key = (String) GameParameterAssist.bd.get(session);
                byte[] raw = key.getBytes("utf-8");
                SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                IvParameterSpec iv = new IvParameterSpec(bU.getBytes("utf-8"));
                cipher.init(2, skeySpec, iv);
                byte[] encrypted1 = new Base64().decode(bytes);
                try {
                    return cipher.doFinal(encrypted1);
                } catch (Exception e) {
                    return null;
                }
            }
            return bytes;
        } catch (Exception ex) {
            logger.error("", ex);
        }
        return null;
    }

    public static byte[] Base64Encode(byte[] bytes, String key) throws Exception {
        byte[] raw = key.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec iv = new IvParameterSpec(bU.getBytes("utf-8"));
        cipher.init(1, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(bytes);
        return new Base64().encode(encrypted);
    }

    public static byte[] Base64Decode(byte[] bytes, String key) throws Exception {
        try {
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(bU.getBytes("utf-8"));
            cipher.init(2, skeySpec, iv);
            byte[] encrypted1 = new Base64().decode(bytes);
            return cipher.doFinal(encrypted1);
        } catch (Exception e) {
        }
        return bytes;
    }

    public static byte[] Base64DecodeParameter(byte[] bytes, String key) throws Exception {
        try {
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec("abcdefghijklmnop".getBytes("utf-8"));
            cipher.init(2, skeySpec, iv);
            byte[] encrypted1 = new Base64().decode(bytes);
            return cipher.doFinal(encrypted1);
        } catch (Exception e) {
        }
        return bytes;
    }

    public static double doubleMultiplyCalculation(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return returnBigDecimalDoubleValue(b1.multiply(b2).doubleValue());
    }

    public static double doubleDivideCalculation(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, 2, 1).doubleValue();
    }

    public static double doubleSubtractCalculation(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return returnBigDecimalDoubleValue(b1.subtract(b2).doubleValue());
    }

    public static double doubleAddCalculation(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return returnBigDecimalDoubleValue(b1.add(b2).doubleValue());
    }

    public static double returnBigDecimalDoubleValue(double dou) {
        BigDecimal bd = new BigDecimal(String.valueOf(dou));
        BigDecimal setScale = bd.setScale(2, 1);
        return setScale.doubleValue();
    }

    public static boolean CalendarIf(Calendar c1, Calendar c2) {
        return (c1.get(1) == c2.get(1)) && (c1.get(2) == c2.get(2));
    }

    public static String getProperties(Object language, String key) {
        if ("0".equals(language.toString())) {
            String str = GameParameterAssist.bI.getProperty(key);
            try {
                return new String(str.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                return str;
            }
        }
        return GameParameterAssist.bJ.getProperty(key);
    }

    public static String getSessionAttribute(IoSession session, String key) {
        return getProperties(session.getAttribute("language"), key);
    }

    public static String DateByDayCalendar(String date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateFormatYMD(date));
        calendar.add(Calendar.DATE, day);
        return dateFormatYMD_Sting(calendar.getTime());
    }

    public static int[] d() {
        int[] lampArray = new int[24];

        int tmpRand1 = e() % 6;
        int tmpRand2 = e() % 6;
        int tmpRand3 = e() % 6;
        while (tmpRand2 == tmpRand1) {
            tmpRand2 = e() % 6;
        }
        while ((tmpRand3 == tmpRand2) || (tmpRand3 == tmpRand1)) {
            tmpRand3 = e() % 6;
        }
        lampArray[(4 * tmpRand1)] = LIGHT_TYPE.bV.f();
        lampArray[(4 * tmpRand2)] = LIGHT_TYPE.bW.f();
        lampArray[(4 * tmpRand3)] = LIGHT_TYPE.bX.f();
        for (int i = 0; i < 6; i++) {
            if ((i != tmpRand1) && (i != tmpRand2) && (i != tmpRand3)) {
                switch (e() % 3) {
                    case 0:
                        lampArray[(4 * i)] = LIGHT_TYPE.bV.f();
                        break;
                    case 1:
                        lampArray[(4 * i)] = LIGHT_TYPE.bW.f();
                        break;
                    case 2:
                        lampArray[(4 * i)] = LIGHT_TYPE.bX.f();
                        break;
                    default:
                        lampArray[(4 * i)] = LIGHT_TYPE.bV.f();
                }
            }
        }
        tmpRand1 = e() % 6;
        tmpRand2 = e() % 6;
        tmpRand3 = e() % 6;
        while (tmpRand2 == tmpRand1) {
            tmpRand2 = e() % 6;
        }
        while ((tmpRand3 == tmpRand2) || (tmpRand3 == tmpRand1)) {
            tmpRand3 = e() % 6;
        }
        lampArray[(4 * tmpRand1 + 1)] = LIGHT_TYPE.bV.f();
        lampArray[(4 * tmpRand2 + 1)] = LIGHT_TYPE.bW.f();
        lampArray[(4 * tmpRand3 + 1)] = LIGHT_TYPE.bX.f();
        for (int i = 0; i < 6; i++) {
            if ((i != tmpRand1) && (i != tmpRand2) && (i != tmpRand3)) {
                switch (e() % 3) {
                    case 0:
                        lampArray[(4 * i + 1)] = LIGHT_TYPE.bV.f();
                        break;
                    case 1:
                        lampArray[(4 * i + 1)] = LIGHT_TYPE.bW.f();
                        break;
                    case 2:
                        lampArray[(4 * i + 1)] = LIGHT_TYPE.bX.f();
                        break;
                    default:
                        lampArray[(4 * i + 1)] = LIGHT_TYPE.bV.f();
                }
            }
        }
        tmpRand1 = e() % 6;
        tmpRand2 = e() % 6;
        tmpRand3 = e() % 6;
        while (tmpRand2 == tmpRand1) {
            tmpRand2 = e() % 6;
        }
        while ((tmpRand3 == tmpRand2) || (tmpRand3 == tmpRand1)) {
            tmpRand3 = e() % 6;
        }
        lampArray[(4 * tmpRand1 + 2)] = LIGHT_TYPE.bV.f();
        lampArray[(4 * tmpRand2 + 2)] = LIGHT_TYPE.bW.f();
        lampArray[(4 * tmpRand3 + 2)] = LIGHT_TYPE.bX.f();
        for (int i = 0; i < 6; i++) {
            if ((i != tmpRand1) && (i != tmpRand2) && (i != tmpRand3)) {
                switch (e() % 3) {
                    case 0:
                        lampArray[(4 * i + 2)] = LIGHT_TYPE.bV.f();
                        break;
                    case 1:
                        lampArray[(4 * i + 2)] = LIGHT_TYPE.bW.f();
                        break;
                    case 2:
                        lampArray[(4 * i + 2)] = LIGHT_TYPE.bX.f();
                        break;
                    default:
                        lampArray[(4 * i + 2)] = LIGHT_TYPE.bV.f();
                }
            }
        }
        tmpRand1 = e() % 6;
        tmpRand2 = e() % 6;
        tmpRand3 = e() % 6;
        while (tmpRand2 == tmpRand1) {
            tmpRand2 = e() % 6;
        }
        while ((tmpRand3 == tmpRand2) || (tmpRand3 == tmpRand1)) {
            tmpRand3 = e() % 6;
        }
        lampArray[(4 * tmpRand1 + 3)] = LIGHT_TYPE.bV.f();
        lampArray[(4 * tmpRand2 + 3)] = LIGHT_TYPE.bW.f();
        lampArray[(4 * tmpRand3 + 3)] = LIGHT_TYPE.bX.f();
        for (int i = 0; i < 6; i++) {
            if ((i != tmpRand1) && (i != tmpRand2) && (i != tmpRand3)) {
                switch (e() % 3) {
                    case 0:
                        lampArray[(4 * i + 3)] = LIGHT_TYPE.bV.f();
                        break;
                    case 1:
                        lampArray[(4 * i + 3)] = LIGHT_TYPE.bW.f();
                        break;
                    case 2:
                        lampArray[(4 * i + 3)] = LIGHT_TYPE.bX.f();
                        break;
                    default:
                        lampArray[(4 * i + 3)] = LIGHT_TYPE.bV.f();
                }
            }
        }
        return lampArray;
    }

    public static int e() {
        return Math.abs(aw.nextInt()) % bS;
    }

    static enum LIGHT_TYPE {
        bV(0), bW(1), bX(2);

        private int nCode;

        public static LIGHT_TYPE[] g() {
            LIGHT_TYPE[] arrayOfLIGHT_TYPE1;
            int i;
            LIGHT_TYPE[] arrayOfLIGHT_TYPE2;
            System.arraycopy(arrayOfLIGHT_TYPE1 = values(), 0, arrayOfLIGHT_TYPE2 = new LIGHT_TYPE[i = arrayOfLIGHT_TYPE1.length], 0, i);
            return arrayOfLIGHT_TYPE2;
        }

        public static LIGHT_TYPE paramString(String paramString) {
            return (LIGHT_TYPE) Enum.valueOf(LIGHT_TYPE.class, paramString);
        }

        private LIGHT_TYPE(int _nCode) {
            this.nCode = _nCode;
        }

        public String toString() {
            return String.valueOf(this.nCode);
        }

        public int f() {
            return this.nCode;
        }
    }

    public static String Base64EncodeToStringSettingExponent(String serverKey, String modulus) {
        return Base64EncodeToString(serverKey, modulus, "AQAB");
    }

    public static String Base64EncodeToString(String serverKey, String modulus, String exponent) {
        try {
            String indexStr = modulus.substring(0, 1);
            String lastStr = modulus.substring(modulus.length() - 1, modulus.length());
            StringBuilder sb = new StringBuilder(modulus.substring(1, modulus.length() - 1));
            String reverseStr = sb.reverse().toString();
            String needStr = StringBuilderSource(reverseStr);
            modulus = indexStr + needStr + lastStr;
            BigInteger b1 = new BigInteger(1, new Base64().decode(modulus));
            BigInteger b2 = new BigInteger(1, new Base64().decode(exponent));
            RSAPublicKeySpec pkSpec = new RSAPublicKeySpec(b1, b2);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicK = keyFactory.generatePublic(pkSpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(1, publicK);
            return new Base64().encodeToString(cipher.doFinal(serverKey.getBytes()));
        } catch (Exception e) {
            logger.error("", e);
        }
        return null;
    }

    private static String StringBuilderSource(String source) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < source.length(); i += 2) {
            if (i + 1 >= source.length()) {
                sb.append(source.charAt(i));
            } else {
                sb.append(source.charAt(i + 1)).append(source.charAt(i));
            }
        }
        return sb.toString();
    }

    public static String format(String msg, Object... paramers) {
        Object[] strParamers = new Object[paramers.length];
        for (int i = 0; i < paramers.length; i++) {
            Object paramer = paramers[i];
            strParamers[i] = (paramer == null ? "NULL" : paramer.toString());
        }
        return MessageFormat.format(msg, strParamers);
    }

    public static String sessionAttributeFormat(IoSession session, String key, Object... paramers) {
        return format(getSessionAttribute(session, key), paramers);
    }

    public static int moneyExchange(double money, int payScale) {
        return (int) doubleDivideCalculation(doubleMultiplyCalculation(money, 100.0D), payScale);
    }

    public static double goldExchange(int gold, int payScale) {
        return doubleDivideCalculation(doubleMultiplyCalculation(gold, payScale), 100.0D);
    }

    public static int[] arrSort(int[] arr) {
        Arrays.sort(arr);
        return arr;
    }

    public static boolean IfCurrentMaxOrMin(int current, int min, int max) {
        return Math.max(min, current) == Math.min(current, max);
    }

    public static void main(String[] args) {
        try {
            InputStream in = MyUtil.class.getClassLoader().getResourceAsStream("com\\miracle9\\game\\util\\Register.class");
            byte[] bs = new byte[in.available()];
            in.read(bs);

            bs = Base64Encode(bs, AuxiliaryCodingKey.key);
            FileOutputStream out = new FileOutputStream("D:\\security.data");
            out.write(bs);
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String strPwdMd5Hex(String strPwd) {
        return DigestUtils.md5Hex(DigestUtils.md5Hex(strPwd) + bT);
    }

    public static double doubleFormat(double dou) {
        DecimalFormat df = new DecimalFormat("0.0");
        return Double.valueOf(df.format(dou)).doubleValue();
    }

}
